"""
智能服装定位算法
基于图像识别技术，自动识别JSON图片应该放置在服装的哪个部位
"""

import cv2
import numpy as np
from PIL import Image, ImageDraw, ImageFont
import json
import requests
from io import BytesIO
from pathlib import Path
from config import Config

try:
    from psd_tools import PSDImage
    PSD_TOOLS_AVAILABLE = True
except ImportError:
    PSD_TOOLS_AVAILABLE = False

class IntelligentGarmentPositioning:
    """
    智能服装定位系统
    """
    
    def __init__(self):
        self.upload_folder = Config.UPLOAD_FOLDER
        self.export_folder = Config.EXPORT_FOLDER
        
        # 服装部位映射
        self.garment_parts = {
            'front': '前胸',
            'back': '后背', 
            'left_sleeve': '左袖',
            'right_sleeve': '右袖',
            'collar': '领口',
            'chest': '胸部',
            'sleeve': '袖子'
        }
        
        # 部位关键词
        self.part_keywords = {
            '前胸': ['front', 'chest', '前', '胸'],
            '后背': ['back', '后', '背'],
            '左袖': ['left', 'sleeve', '左', '袖'],
            '右袖': ['right', 'sleeve', '右', '袖'],
            '领口': ['collar', 'neck', '领', '口']
        }
    
    def analyze_garment_structure(self, psd_path, mask_image_path=None, preview_image_path=None):
        """
        分析服装结构，识别各个部位
        
        Args:
            psd_path: PSD底板文件路径
            mask_image_path: 定制区域查看图路径
            preview_image_path: 合成预览图路径
            
        Returns:
            dict: 服装部位分析结果
        """
        print("=== 开始分析服装结构 ===")
        
        analysis_result = {
            'garment_parts': {},
            'regions_mapping': {},
            'psd_layers': [],
            'size': (0, 0)
        }
        
        # 1. 分析PSD文件的图层结构
        if PSD_TOOLS_AVAILABLE and Path(psd_path).exists():
            try:
                psd = PSDImage.open(psd_path)
                analysis_result['size'] = (psd.width, psd.height)
                
                print(f"PSD尺寸: {psd.width} x {psd.height}")
                
                # 分析图层名称，识别服装部位
                for layer in psd:
                    layer_name = layer.name.lower()
                    detected_part = self._detect_garment_part_from_name(layer_name)
                    
                    if detected_part:
                        layer_info = {
                            'name': layer.name,
                            'detected_part': detected_part,
                            'visible': layer.visible,
                            'is_group': layer.is_group()
                        }
                        
                        # 获取图层边界
                        if hasattr(layer, 'bbox') and layer.bbox:
                            try:
                                bbox = layer.bbox
                                if hasattr(bbox, 'width'):
                                    layer_info['bbox'] = {
                                        'x': bbox.x1, 'y': bbox.y1,
                                        'width': bbox.width, 'height': bbox.height,
                                        'center_x': bbox.x1 + bbox.width // 2,
                                        'center_y': bbox.y1 + bbox.height // 2
                                    }
                            except:
                                pass
                        
                        analysis_result['psd_layers'].append(layer_info)
                        analysis_result['garment_parts'][detected_part] = layer_info
                        
                        print(f"识别部位: {layer.name} → {detected_part}")
                
            except Exception as e:
                print(f"PSD分析失败: {e}")
        
        # 2. 分析mask图像（如果提供）
        if mask_image_path and Path(mask_image_path).exists():
            mask_analysis = self._analyze_mask_image(mask_image_path)
            analysis_result['mask_regions'] = mask_analysis
        
        print(f"识别到 {len(analysis_result['garment_parts'])} 个服装部位")
        return analysis_result
    
    def _detect_garment_part_from_name(self, layer_name):
        """从图层名称检测服装部位"""
        layer_name = layer_name.lower()
        
        for part, keywords in self.part_keywords.items():
            for keyword in keywords:
                if keyword in layer_name:
                    return part
        
        return None
    
    def _analyze_mask_image(self, mask_path):
        """分析mask图像，识别定制区域"""
        try:
            # 使用OpenCV分析mask图像
            mask_img = cv2.imread(str(mask_path))
            if mask_img is None:
                return {}
            
            # 转换为灰度图
            gray = cv2.cvtColor(mask_img, cv2.COLOR_BGR2GRAY)
            
            # 查找轮廓
            contours, _ = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
            
            regions = []
            for i, contour in enumerate(contours):
                # 获取边界矩形
                x, y, w, h = cv2.boundingRect(contour)
                area = cv2.contourArea(contour)
                
                if area > 1000:  # 过滤小区域
                    regions.append({
                        'index': i,
                        'bbox': {'x': x, 'y': y, 'width': w, 'height': h},
                        'area': area,
                        'center': {'x': x + w//2, 'y': y + h//2}
                    })
            
            print(f"在mask图像中发现 {len(regions)} 个定制区域")
            return regions
            
        except Exception as e:
            print(f"mask图像分析失败: {e}")
            return {}
    
    def intelligent_position_json_images(self, psd_path, json_data, regions_data=None):
        """
        智能定位JSON图片到服装部位
        
        Args:
            psd_path: PSD文件路径
            json_data: JSON配置数据
            regions_data: 定制区域数据
            
        Returns:
            dict: 智能定位结果
        """
        print("=== 开始智能图片定位 ===")
        
        # 1. 分析服装结构
        garment_analysis = self.analyze_garment_structure(psd_path)
        
        # 2. 分析JSON图片内容
        json_images = self._extract_json_images(json_data)
        
        # 3. 智能匹配部位
        positioning_result = {
            'matches': [],
            'garment_analysis': garment_analysis,
            'total_images': len(json_images)
        }
        
        for i, json_image in enumerate(json_images):
            # 下载并分析图片内容
            image_analysis = self._analyze_json_image_content(json_image)
            
            # 基于内容和位置信息推测部位
            suggested_part = self._suggest_garment_part(image_analysis, garment_analysis)
            
            # 计算最佳位置
            optimal_position = self._calculate_optimal_position(
                suggested_part, garment_analysis, regions_data, json_image
            )
            
            match_result = {
                'image_index': i,
                'image_url': json_image['url'],
                'original_position': json_image['position'],
                'suggested_part': suggested_part,
                'optimal_position': optimal_position,
                'confidence': image_analysis.get('confidence', 0.5),
                'reasoning': image_analysis.get('reasoning', '基于位置推测')
            }
            
            positioning_result['matches'].append(match_result)
            
            print(f"图片 {i+1}: {suggested_part} → 位置({optimal_position['x']}, {optimal_position['y']})")
        
        return positioning_result
    
    def _extract_json_images(self, json_data):
        """从JSON数据中提取图片信息"""
        images = []
        
        if json_data.get('surfaces'):
            for surface in json_data['surfaces']:
                mask_image_url = None
                
                # 动态获取JSON基础尺寸
                json_base_width = 1340  # 默认值
                json_base_height = 1340  # 默认值
                
                # 优先使用baseImage尺寸
                if surface.get('baseImage') and surface['baseImage'].get('dimension'):
                    base_dim = surface['baseImage']['dimension']
                    json_base_width = base_dim.get('width', 1340)
                    json_base_height = base_dim.get('height', 1340)
                    print(f"使用JSON基础尺寸（baseImage）: {json_base_width}x{json_base_height}")
                # 其次使用base_image尺寸
                elif surface.get('base_image') and surface['base_image'].get('dimension'):
                    base_dim = surface['base_image']['dimension']
                    json_base_width = base_dim.get('width', 1340)
                    json_base_height = base_dim.get('height', 1340)
                    print(f"使用JSON基础尺寸（base_image）: {json_base_width}x{json_base_height}")
                # 再次使用maskImage尺寸
                elif surface.get('maskImage') and surface['maskImage'].get('dimension'):
                    mask_dim = surface['maskImage']['dimension']
                    json_base_width = mask_dim.get('width', 1340)
                    json_base_height = mask_dim.get('height', 1340)
                    print(f"使用JSON基础尺寸（maskImage）: {json_base_width}x{json_base_height}")
                # 最后使用mask_image尺寸
                elif surface.get('mask_image') and surface['mask_image'].get('dimension'):
                    mask_dim = surface['mask_image']['dimension']
                    json_base_width = mask_dim.get('width', 1340)
                    json_base_height = mask_dim.get('height', 1340)
                    print(f"使用JSON基础尺寸（mask_image）: {json_base_width}x{json_base_height}")
                else:
                    print(f"未找到JSON基础尺寸，使用默认值: {json_base_width}x{json_base_height}")
                
                # 存储到实例变量供后续使用
                self.json_base_width = json_base_width
                self.json_base_height = json_base_height
                
                # 揔取maskImage信息
                if surface.get('maskImage'):
                    mask_image_url = surface['maskImage'].get('imageUrl')
                    print(f"找到maskImage: {mask_image_url}")
                
                if surface.get('regions'):
                    for region in surface['regions']:
                        if region.get('elements'):
                            for element in region['elements']:
                                # 支持两种字段名称格式
                                image_url = element.get('imageUrl') or element.get('image_url')
                                if image_url:
                                    # 支持两种 placement 字段格式
                                    placement = element.get('userPlacementData') or element.get('user_placement_data', {})
                                    position = placement.get('position', {})
                                    dimension = placement.get('dimension', {})
                                    
                                    images.append({
                                        'url': image_url,
                                        'position': position,
                                        'dimension': dimension,
                                        'scale': placement.get('scale', {}),
                                        'rotation': placement.get('angleOfRotation', 0),
                                        'mask_image_url': mask_image_url  # 添加mask图片URL
                                    })
        
        print(f"提取了 {len(images)} 个JSON图片")
        return images
    
    def _analyze_json_image_content(self, json_image):
        """分析JSON图片位置信息，不下载实际图片"""
        try:
            # 只分析位置信息，不下载图片
            original_pos = json_image['position']
            dimension = json_image['dimension']
            
            # 使用动态获取的JSON基础尺寸
            base_width = getattr(self, 'json_base_width', 1340)
            base_height = getattr(self, 'json_base_height', 1340)
            
            x_percent = original_pos.get('x', 0) / base_width
            y_percent = original_pos.get('y', 0) / base_height
            
            # 基于位置的部位推测逻辑
            suggested_part = '前胸'  # 默认
            confidence = 0.5
            reasoning = '基于位置分析'
            
            print(f"位置分析: JSON({original_pos.get('x', 0)}, {original_pos.get('y', 0)}) / 基础尺寸({base_width}x{base_height}) → 相对位置({x_percent:.2f}, {y_percent:.2f})")
            
            if y_percent < 0.25:
                suggested_part = '领口'
                confidence = 0.8
                reasoning = '位置在上部区域，推测为领口部位'
            elif x_percent < 0.3:
                suggested_part = '左袖'
                confidence = 0.7
                reasoning = '位置在左侧区域，推测为左袖部位'
            elif x_percent > 0.7:
                suggested_part = '右袖'
                confidence = 0.7
                reasoning = '位置在右侧区域，推测为右袖部位'
            elif 0.25 <= y_percent <= 0.75:
                suggested_part = '前胸'
                confidence = 0.9
                reasoning = '位置在中心区域，推测为前胸部位'
            else:
                suggested_part = '后背'
                confidence = 0.6
                reasoning = '位置在下部区域，推测为后背部位'
            
            return {
                'suggested_part': suggested_part,
                'confidence': confidence,
                'reasoning': reasoning,
                'original_position': original_pos,
                'relative_position': {'x': x_percent, 'y': y_percent},
                'dimension': dimension
            }
            
        except Exception as e:
            print(f"位置分析失败: {e}")
            return {
                'suggested_part': '前胸',
                'confidence': 0.1,
                'reasoning': f'分析失败: {e}'
            }
    
    def _get_dominant_colors(self, image, k=3):
        """获取图片的主要颜色"""
        try:
            # 重塑图像数据
            data = image.reshape((-1, 3))
            data = np.float32(data)
            
            # K-means聚类
            criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 20, 1.0)
            _, labels, centers = cv2.kmeans(data, k, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
            
            # 转换为整数
            centers = np.uint8(centers)
            
            return centers.tolist()
        except:
            return [[128, 128, 128]]  # 默认灰色
    
    def _suggest_garment_part(self, image_analysis, garment_analysis):
        """基于图片分析结果推荐服装部位"""
        suggested_part = image_analysis.get('suggested_part', '前胸')
        
        # 检查推荐的部位是否在PSD中存在
        available_parts = list(garment_analysis['garment_parts'].keys())
        
        if suggested_part in available_parts:
            return suggested_part
        
        # 如果推荐部位不存在，选择最相似的
        if '前胸' in available_parts:
            return '前胸'
        elif available_parts:
            return available_parts[0]
        else:
            return '前胸'  # 默认
    
    def _calculate_optimal_position(self, suggested_part, garment_analysis, regions_data, json_image):
        """计算最佳位置 - 优先使用JSON原始位置进行比例转换"""
        # 获取JSON原始位置和尺寸
        original_pos = json_image.get('position', {})
        original_dim = json_image.get('dimension', {})
        
        # 获取实际PSD尺寸
        psd_analysis = garment_analysis.get('size', (9314, 5663))
        psd_width, psd_height = psd_analysis
        
        # 获取JSON基础尺寸
        json_base_width = getattr(self, 'json_base_width', 1340)
        json_base_height = getattr(self, 'json_base_height', 1340)
        
        # 计算缩放比例
        scale_x = psd_width / json_base_width
        scale_y = psd_height / json_base_height
        
        # 转换位置坐标
        psd_x = original_pos.get('x', 0) * scale_x
        psd_y = original_pos.get('y', 0) * scale_y
        
        # 转换尺寸，但限制最大尺寸以适应预览
        json_width = original_dim.get('width', 300)
        json_height = original_dim.get('height', 300)
        
        # 计算转换后的PSD尺寸
        psd_width_size = json_width * scale_x
        psd_height_size = json_height * scale_y
        
        # 如果转换后的尺寸过大，进行适当缩放以适应预览
        max_preview_width = psd_width * 0.3  # 最大不超过PSD宽度的30%
        max_preview_height = psd_height * 0.3  # 最大不超过PSD高度的30%
        
        if psd_width_size > max_preview_width or psd_height_size > max_preview_height:
            # 计算缩放比例
            width_scale = max_preview_width / psd_width_size if psd_width_size > max_preview_width else 1
            height_scale = max_preview_height / psd_height_size if psd_height_size > max_preview_height else 1
            preview_scale = min(width_scale, height_scale)
            
            psd_width_size *= preview_scale
            psd_height_size *= preview_scale
            
            print(f"尺寸限制: 原始PSD尺寸({json_width * scale_x:.1f}, {json_height * scale_y:.1f}) -> 预览适配尺寸({psd_width_size:.1f}, {psd_height_size:.1f})")
        
        print(f"位置转换: JSON({original_pos.get('x', 0)}, {original_pos.get('y', 0)}) -> PSD({psd_x:.1f}, {psd_y:.1f})")
        print(f"尺寸转换: JSON({json_width}, {json_height}) -> PSD({psd_width_size:.1f}, {psd_height_size:.1f})")
        print(f"缩放比例: x{scale_x:.2f}, y{scale_y:.2f} | JSON基础: {json_base_width}x{json_base_height} | PSD: {psd_width}x{psd_height}")
        print(f"预览适配: 最终尺寸适合前端显示 ({psd_width_size:.1f}x{psd_height_size:.1f})")
        
        # 返回转换后的PSD坐标和适配后的尺寸
        return {
            'x': psd_x,
            'y': psd_y,
            'width': psd_width_size,
            'height': psd_height_size,
            'method': 'json_position_scaled_adaptive',
            'scale_x': scale_x,
            'scale_y': scale_y,
            'json_base_size': f'{json_base_width}x{json_base_height}',
            'psd_size': f'{psd_width}x{psd_height}',
            'original_json_size': f'{json_width}x{json_height}',
            'final_preview_size': f'{psd_width_size:.1f}x{psd_height_size:.1f}'
        }
        
        # 以下是原始的图层匹配逻辑（作为备用，当前不使用）
        # part_info = garment_analysis['garment_parts'].get(suggested_part)
        
        if part_info and part_info.get('bbox'):
            # 使用PSD图层的中心位置
            bbox = part_info['bbox']
            center_x = bbox['center_x']
            center_y = bbox['center_y']
            
            print(f"使用{suggested_part}图层中心: ({center_x}, {center_y})")
            
            # 如果有定制区域数据，优先使用最近的区域
            if regions_data:
                closest_region = self._find_closest_region(center_x, center_y, regions_data)
                if closest_region:
                    region_center_x = closest_region['x'] + closest_region['width'] // 2
                    region_center_y = closest_region['y'] + closest_region['height'] // 2
                    
                    print(f"使用最近的定制区域中心: ({region_center_x}, {region_center_y})")
                    return {
                        'x': region_center_x,
                        'y': region_center_y,
                        'width': closest_region['width'],
                        'height': closest_region['height'],
                        'region_id': closest_region.get('id'),
                        'method': 'region_based'
                    }
            
            return {
                'x': center_x,
                'y': center_y,
                'width': bbox['width'],
                'height': bbox['height'],
                'method': 'layer_based'
            }
        else:
            # 回退到原始位置
            original_pos = json_image['position']
            return {
                'x': original_pos.get('x', 0),
                'y': original_pos.get('y', 0),
                'width': json_image['dimension'].get('width', 200),
                'height': json_image['dimension'].get('height', 200),
                'method': 'original'
            }
    
    def _find_closest_region(self, x, y, regions_data):
        """找到最接近指定位置的定制区域"""
        closest_region = None
        min_distance = float('inf')
        
        for region in regions_data:
            region_center_x = region['x'] + region['width'] // 2
            region_center_y = region['y'] + region['height'] // 2
            
            distance = np.sqrt((x - region_center_x)**2 + (y - region_center_y)**2)
            
            if distance < min_distance:
                min_distance = distance
                closest_region = region
        
        return closest_region
    
    def create_intelligent_layout(self, template_id, json_data, regions_data=None):
        """
        创建智能布局
        
        Args:
            template_id: 模板ID
            json_file_path: JSON文件路径
            
        Returns:
            dict: 智能布局结果
        """
        print("=== 创建智能布局 ===")
        
        # 1. 获取模板和区域信息
        from database import template_dao, region_dao
        
        template = template_dao.get_template_by_id(template_id)
        if not template:
            return {'error': '模板不存在'}
        
        regions = region_dao.get_regions_by_template(template_id)
        regions_data = [dict(region) for region in regions] if regions else []
        
        # 2. 验证JSON数据
        if not json_data:
            return {'error': 'JSON数据为空'}
        
        # 3. 分析服装结构
        psd_path = template['image_path']
        garment_analysis = self.analyze_garment_structure(psd_path)
        
        # 4. 智能定位
        positioning_result = self.intelligent_position_json_images(
            psd_path, json_data, regions_data
        )
        
        if not positioning_result:
            return {'error': '智能定位失败'}
        
        # 5. 应用智能适配算法
        enhanced_result = self._apply_intelligent_matching_algorithm(
            positioning_result, regions_data, template
        )
        
        # 6. 生成适配后的配置
        adapted_config = self._generate_adapted_config(
            enhanced_result, garment_analysis, regions_data
        )
        
        return {
            'success': True,
            'garment_analysis': garment_analysis,
            'positioning_result': positioning_result,
            'adapted_config': adapted_config,
            'regions_count': len(regions_data)
        }
    
    def _generate_adapted_config(self, positioning_result, garment_analysis, regions_data):
        """生成适配后的配置"""
        adapted_regions = {}
        
        for i, match in enumerate(positioning_result['matches']):
            optimal_pos = match['optimal_position']
            
            # 计算适配后的尺寸
            if optimal_pos['method'] == 'region_based' and regions_data:
                # 使用区域尺寸
                target_width = optimal_pos['width']
                target_height = optimal_pos['height']
            else:
                # 使用原始尺寸或默认尺寸
                target_width = optimal_pos.get('width', 300)
                target_height = optimal_pos.get('height', 300)
            
            # 创建适配后的元素配置
            adapted_element = {
                'image_url': match['image_url'],
                'user_placement_data': {
                    'position': {
                        'x': optimal_pos['x'],
                        'y': optimal_pos['y']
                    },
                    'dimension': {
                        'width': target_width,
                        'height': target_height
                    },
                    'scale': {'scale_x': 1.0, 'scale_y': 1.0},
                    'angle_of_rotation': 0
                },
                'intelligent_info': {
                    'suggested_part': match['suggested_part'],
                    'confidence': match['confidence'],
                    'method': optimal_pos['method'],
                    'reasoning': match['reasoning']
                }
            }
            
            region_index = str(optimal_pos.get('region_id', i))
            if region_index not in adapted_regions:
                adapted_regions[region_index] = {'elements': []}
            
            adapted_regions[region_index]['elements'].append(adapted_element)
        
        return {'regions': adapted_regions}
    
    def intelligent_position_json_images(self, psd_path, json_data, regions_data=None):
        """
        智能定位 JSON 图片
        """
        print("开始智能图片定位...")
        
        # 1. 分析服装结构
        garment_analysis = self.analyze_garment_structure(psd_path)
        
        # 2. 提取JSON图片
        json_images = self._extract_json_images(json_data)
        
        if not json_images:
            return {
                'matches': [],
                'garment_analysis': garment_analysis,
                'total_images': 0
            }
        
        # 3. 为每个图片进行智能定位
        matches = []
        
        for i, json_image in enumerate(json_images):
            try:
                # 分析图片内容
                image_analysis = self._analyze_json_image_content(json_image)
                
                # 推荐服装部位
                suggested_part = self._suggest_garment_part(image_analysis, garment_analysis)
                
                # 计算最佳位置
                optimal_position = self._calculate_optimal_position(
                    suggested_part, garment_analysis, regions_data, json_image
                )
                
                match = {
                    'image_index': i,
                    'image_url': json_image['url'],
                    'original_position': json_image['position'],
                    'suggested_part': suggested_part,
                    'optimal_position': optimal_position,
                    'confidence': image_analysis.get('confidence', 0.5),
                    'reasoning': image_analysis.get('reasoning', '基于位置推测')
                }
                
                matches.append(match)
                print(f"图片 {i+1}: {suggested_part} → 位置({optimal_position['x']}, {optimal_position['y']})")
                
            except Exception as e:
                print(f"处理图片 {i+1} 失败: {e}")
                continue
        
        return {
            'matches': matches,
            'garment_analysis': garment_analysis,
            'total_images': len(json_images)
        }
    
    def _apply_intelligent_matching_algorithm(self, positioning_result, regions_data, template):
        """
        应用智能适配算法：根据底板定制区域数量和JSON识别图片数量的关系，
        按照大小和位置进行最优匹配
        
        Args:
            positioning_result: 初步定位结果
            regions_data: 底板定制区域数据
            template: 底板模板信息
            
        Returns:
            dict: 增强后的定位结果
        """
        print("=== 应用智能适配算法 ===")
        
        matches = positioning_result.get('matches', [])
        if not matches:
            return positioning_result
        
        regions_count = len(regions_data)
        images_count = len(matches)
        
        print(f"底板定制区域数量: {regions_count}")
        print(f"JSON识别图片数量: {images_count}")
        
        # 根据数量关系选择适配策略
        if regions_count == 0:
            # 没有定制区域，保持原始位置
            return self._keep_original_positions(positioning_result)
        elif regions_count == 1:
            # 一个定制区域，多个图片的情况
            return self._handle_single_region_multiple_images(positioning_result, regions_data[0])
        elif regions_count == images_count:
            # 数量相等，一对一匹配
            return self._handle_equal_count_matching(positioning_result, regions_data)
        elif regions_count > images_count:
            # 区域多于图片，选择最佳区域
            return self._handle_more_regions_than_images(positioning_result, regions_data)
        else:
            # 图片多于区域，选择最合适的图片
            return self._handle_more_images_than_regions(positioning_result, regions_data)
    
    def _keep_original_positions(self, positioning_result):
        """保持原始位置不变"""
        print("策略: 保持原始位置")
        for match in positioning_result['matches']:
            original_pos = match['original_position']
            match['optimal_position'].update({
                'x': original_pos.get('x', match['optimal_position']['x']),
                'y': original_pos.get('y', match['optimal_position']['y']),
                'adaptation_method': 'keep_original'
            })
        return positioning_result
    
    def _handle_single_region_multiple_images(self, positioning_result, single_region):
        """处理单个定制区域，多个图片的情况"""
        print("策略: 单区域多图片 - 选择最合适的图片")
        
        matches = positioning_result['matches']
        if not matches:
            return positioning_result
        
        # 按照大小和置信度评分
        scored_matches = []
        region_area = single_region['width'] * single_region['height']
        
        for i, match in enumerate(matches):
            # 计算图片与区域的尺寸匹配度
            image_area = match['optimal_position'].get('width', 300) * match['optimal_position'].get('height', 300)
            size_score = min(image_area, region_area) / max(image_area, region_area)
            
            # 计算位置匹配度（距离区域中心的距离）
            region_center_x = single_region['x'] + single_region['width'] // 2
            region_center_y = single_region['y'] + single_region['height'] // 2
            
            image_x = match['optimal_position']['x']
            image_y = match['optimal_position']['y']
            
            distance = np.sqrt((image_x - region_center_x)**2 + (image_y - region_center_y)**2)
            max_distance = np.sqrt(single_region['width']**2 + single_region['height']**2)
            position_score = max(0, 1 - distance / max_distance)
            
            # 综合评分
            confidence = match.get('confidence', 0.5)
            total_score = (size_score * 0.4 + position_score * 0.4 + confidence * 0.2)
            
            scored_matches.append({
                'index': i,
                'match': match,
                'score': total_score,
                'size_score': size_score,
                'position_score': position_score
            })
            
            print(f"图片 {i+1}: 尺寸匹配={size_score:.2f}, 位置匹配={position_score:.2f}, 总分={total_score:.2f}")
        
        # 选择得分最高的图片进行适配
        best_match = max(scored_matches, key=lambda x: x['score'])
        best_index = best_match['index']
        
        print(f"选择图片 {best_index+1} 进行适配到定制区域")
        
        # 更新最佳匹配的位置
        matches[best_index]['optimal_position'].update({
            'x': single_region['x'],
            'y': single_region['y'],
            'width': single_region['width'],
            'height': single_region['height'],
            'region_id': single_region.get('id'),
            'adaptation_method': 'best_fit_single_region',
            'adaptation_score': best_match['score']
        })
        
        # 其他图片保持原始位置
        for i, match in enumerate(matches):
            if i != best_index:
                original_pos = match['original_position']
                match['optimal_position'].update({
                    'adaptation_method': 'keep_original_position'
                })
                print(f"图片 {i+1} 保持原始位置")
        
        return positioning_result
    
    def _handle_equal_count_matching(self, positioning_result, regions_data):
        """处理数量相等的一对一匹配"""
        print("策略: 一对一最优匹配")
        
        matches = positioning_result['matches']
        
        # 使用匈牙利算法或贪心算法进行最优匹配
        cost_matrix = []
        
        for i, match in enumerate(matches):
            costs = []
            for j, region in enumerate(regions_data):
                # 计算匹配成本（距离 + 尺寸差异）
                image_x = match['optimal_position']['x']
                image_y = match['optimal_position']['y']
                region_center_x = region['x'] + region['width'] // 2
                region_center_y = region['y'] + region['height'] // 2
                
                distance = np.sqrt((image_x - region_center_x)**2 + (image_y - region_center_y)**2)
                
                # 尺寸差异
                image_area = match['optimal_position'].get('width', 300) * match['optimal_position'].get('height', 300)
                region_area = region['width'] * region['height']
                size_diff = abs(image_area - region_area) / max(image_area, region_area)
                
                # 综合成本（距离权重0.6，尺寸差异权重0.4）
                cost = distance * 0.6 + size_diff * 1000 * 0.4
                costs.append(cost)
            
            cost_matrix.append(costs)
        
        # 使用贪心算法进行匹配
        used_regions = set()
        assignments = {}
        
        # 按成本排序所有可能的匹配
        all_matches = []
        for i in range(len(matches)):
            for j in range(len(regions_data)):
                all_matches.append((cost_matrix[i][j], i, j))
        
        all_matches.sort()  # 按成本升序排列
        
        # 贪心分配
        for cost, match_idx, region_idx in all_matches:
            if match_idx not in assignments and region_idx not in used_regions:
                assignments[match_idx] = region_idx
                used_regions.add(region_idx)
        
        # 应用匹配结果
        for match_idx, region_idx in assignments.items():
            region = regions_data[region_idx]
            matches[match_idx]['optimal_position'].update({
                'x': region['x'],
                'y': region['y'],
                'width': region['width'],
                'height': region['height'],
                'region_id': region.get('id'),
                'adaptation_method': 'optimal_assignment',
                'assignment_cost': cost_matrix[match_idx][region_idx]
            })
            
            print(f"图片 {match_idx+1} → 区域 {region_idx+1} (成本: {cost_matrix[match_idx][region_idx]:.2f})")
        
        return positioning_result
    
    def _handle_more_regions_than_images(self, positioning_result, regions_data):
        """处理区域多于图片的情况"""
        print("策略: 区域多于图片 - 选择最佳区域")
        
        matches = positioning_result['matches']
        
        for i, match in enumerate(matches):
            # 为每个图片找到最适合的区域
            best_region = None
            best_score = -1
            
            image_x = match['optimal_position']['x']
            image_y = match['optimal_position']['y']
            image_area = match['optimal_position'].get('width', 300) * match['optimal_position'].get('height', 300)
            
            for region in regions_data:
                region_center_x = region['x'] + region['width'] // 2
                region_center_y = region['y'] + region['height'] // 2
                
                # 距离得分
                distance = np.sqrt((image_x - region_center_x)**2 + (image_y - region_center_y)**2)
                max_distance = np.sqrt(region['width']**2 + region['height']**2)
                distance_score = max(0, 1 - distance / max_distance)
                
                # 尺寸得分
                region_area = region['width'] * region['height']
                size_score = min(image_area, region_area) / max(image_area, region_area)
                
                # 综合得分
                total_score = distance_score * 0.6 + size_score * 0.4
                
                if total_score > best_score:
                    best_score = total_score
                    best_region = region
            
            if best_region:
                matches[i]['optimal_position'].update({
                    'x': best_region['x'],
                    'y': best_region['y'],
                    'width': best_region['width'],
                    'height': best_region['height'],
                    'region_id': best_region.get('id'),
                    'adaptation_method': 'best_region_selection',
                    'selection_score': best_score
                })
                
                print(f"图片 {i+1} → 最佳区域 (得分: {best_score:.2f})")
        
        return positioning_result
    
    def _handle_more_images_than_regions(self, positioning_result, regions_data):
        """处理图片多于区域的情况"""
        print("策略: 图片多于区域 - 选择最合适的图片")
        
        matches = positioning_result['matches']
        
        # 为每个区域找到最适合的图片
        region_assignments = {}
        
        for region_idx, region in enumerate(regions_data):
            best_match = None
            best_score = -1
            best_match_idx = -1
            
            region_center_x = region['x'] + region['width'] // 2
            region_center_y = region['y'] + region['height'] // 2
            region_area = region['width'] * region['height']
            
            for match_idx, match in enumerate(matches):
                # 跳过已经分配的图片
                if match_idx in [assigned[1] for assigned in region_assignments.values()]:
                    continue
                
                image_x = match['optimal_position']['x']
                image_y = match['optimal_position']['y']
                image_area = match['optimal_position'].get('width', 300) * match['optimal_position'].get('height', 300)
                
                # 距离得分
                distance = np.sqrt((image_x - region_center_x)**2 + (image_y - region_center_y)**2)
                max_distance = np.sqrt(region['width']**2 + region['height']**2)
                distance_score = max(0, 1 - distance / max_distance)
                
                # 尺寸得分
                size_score = min(image_area, region_area) / max(image_area, region_area)
                
                # 置信度
                confidence = match.get('confidence', 0.5)
                
                # 综合得分
                total_score = distance_score * 0.4 + size_score * 0.4 + confidence * 0.2
                
                if total_score > best_score:
                    best_score = total_score
                    best_match = match
                    best_match_idx = match_idx
            
            if best_match:
                region_assignments[region_idx] = (best_match, best_match_idx, best_score)
                print(f"区域 {region_idx+1} ← 图片 {best_match_idx+1} (得分: {best_score:.2f})")
        
        # 应用分配结果
        assigned_matches = set()
        for region_idx, (match, match_idx, score) in region_assignments.items():
            region = regions_data[region_idx]
            matches[match_idx]['optimal_position'].update({
                'x': region['x'],
                'y': region['y'],
                'width': region['width'],
                'height': region['height'],
                'region_id': region.get('id'),
                'adaptation_method': 'best_image_selection',
                'selection_score': score
            })
            assigned_matches.add(match_idx)
        
        # 未分配的图片保持原始位置
        for i, match in enumerate(matches):
            if i not in assigned_matches:
                original_pos = match['original_position']
                match['optimal_position'].update({
                    'adaptation_method': 'keep_original_unassigned'
                })
                print(f"图片 {i+1} 未分配，保持原始位置")
        
        return positioning_result
